package boundary;

import java.awt.Font;
import java.awt.Graphics;
import java.util.ArrayList;

import model.TaskElement;
import model.Tasks;
import util.IniParameters;

public class LeftPartDrawer {
	private final int m_marginLeft = 10;
	private final int m_marginRight = 10;
	private final int m_marginTop = IniParameters.topPanelHeight + 20;
	private final int m_marginBottom = IniParameters.marginBottom;
	private final int m_areaHeight = IniParameters.appletHeight - m_marginTop
			- m_marginBottom;
	private final int m_areaWidth = IniParameters.leftPartWidth - m_marginLeft
			- m_marginRight;
	private final int m_elevatorWidth = 100;
	private final int m_floorMarkerWidth = 20;
	private final int m_leftWidth = m_floorMarkerWidth + m_elevatorWidth + 10;
	private final int m_rightWidth = m_areaWidth - m_leftWidth;

	private int m_nWaitingStatesForDrawing = IniParameters.numberOfWaitingStates + 1;
	private int m_nFloors = IniParameters.numberOfFloors;
	private int m_floorHeight = m_areaHeight / m_nFloors;
	private Tasks m_tasks;

	private int m_totalDistance = 0;
	private int m_previousFloor = 0;
	private int m_currentFloor = 0;

	public int getTotalDistance() {
		return m_totalDistance;
	}

	public void drawLeftPart(Graphics g, int currentFloor, Tasks tasks) {
		// calculate total distance
		m_previousFloor = m_currentFloor;
		m_currentFloor = currentFloor;
		m_totalDistance += Math.abs(m_currentFloor - m_previousFloor);

		m_tasks = tasks;

		paintTitle(g);
		paintElevator(g);
		paintFloors(g);
		paintStatistics(g);
	}

	private void paintTitle(Graphics g) {
		String title = "Our Lift";
		Font oringinal = g.getFont();
		Font big = new Font(null, 20, 20);
		g.setFont(big);
		g.drawString(title, 30, 90);
		g.setFont(oringinal);

		String description = "(Detect passengers using smart phone)";
		g.drawString(description, 10, 110);
	}

	private void paintStatistics(Graphics g) {
		String strDistance = "Total distance: " + m_totalDistance + " floors.";
		g.drawString(strDistance, getRealX(50), getRealY(-20));
		String strTime = "Avarage Waiting Time: "
				+ m_tasks.getAverageWaitingTime() + "seconds. ";
		g.drawString(strTime, getRealX(20), getRealY(-40));
	}

	private void paintFloors(Graphics g) {
		for (int i = 0; i < m_nFloors; i++) {
			int x1 = getRealX(m_leftWidth);
			int y1 = getRealY(i * m_floorHeight);
			int x2 = getRealX(m_areaWidth);
			int y2 = getRealY(i * m_floorHeight);
			// draw the floor line
			g.drawLine(x1, y1, x2, y2);
			// draw the tasks of this floor
			paintFloorTasks(g, x1, y1 - 10, i);
		}
	}

	private void paintFloorTasks(Graphics g, int x, int y, int floor) {
		String[] output = new String[m_nWaitingStatesForDrawing];
		for (int i = 0; i < m_nWaitingStatesForDrawing; i++) {
			output[i] = "";
		}
		ArrayList<TaskElement> vFloorTasks = m_tasks.getTasksOfFloor(floor);
		for (TaskElement te : vFloorTasks) {
			int state = (int) te.getTimeUnit();
			output[state] += " " + te.getDest();
		}

		int distanceUnit = m_rightWidth / m_nWaitingStatesForDrawing;
		for (int i = 0; i < m_nWaitingStatesForDrawing; i++)
			g.drawString(output[i], x + distanceUnit * i, y);
	}

	private void paintElevator(Graphics g) {
		// draw the elevator boundary
		g.drawRect(getRealX(m_floorMarkerWidth), getRealY(m_areaHeight),
				m_elevatorWidth, m_areaHeight);

		// draw the floor index
		for (int i = 0; i < m_nFloors; i++) {
			int x = getRealX(0);
			int y = getRealY(i * m_floorHeight + 10);
			g.drawString(Integer.toString(i), x, y);
		}

		// draw the elevator box
		int currentFloor = m_currentFloor;
		int x_box = getRealX(m_floorMarkerWidth + 10);
		int y_box = getRealY((currentFloor + 1) * m_floorHeight - 5);
		int width = m_elevatorWidth - 20;
		int height = m_floorHeight - 10;
		g.drawRect(x_box, y_box, width, height);

		// draw the passengers
		printPassengers(g, currentFloor);
	}

	private void printPassengers(Graphics g, int currentFloor) {
		ArrayList<TaskElement> vPassengers = m_tasks.getState();
		String strPassengers = "";
		for (int i = 0; i < vPassengers.size(); i++) {
			strPassengers += vPassengers.get(i).getDest() + " ";
		}
		int x_passengers = getRealX(35);
		int y_passengers = getRealY((currentFloor) * m_floorHeight + 10);
		g.drawString(strPassengers, x_passengers, y_passengers);
	}

	private int getRealX(int x) {
		return x + m_marginLeft;
	}

	private int getRealY(int y) {
		return m_marginTop + m_areaHeight - y;
	}
}
